package com.clpms.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.clpms.bean.enumBean.EasyTypeEnum;
import com.clpms.bean.enumBean.ErrorCodeEnum;
import com.clpms.bean.enumBean.LearnRecordProgress;
import com.clpms.bean.req.DeleteLearnRecordReq;
import com.clpms.bean.req.LearnRecordAddReq;
import com.clpms.bean.req.UpdateLearnRecordReq;
import com.clpms.bean.resp.UploadLearnRecordResp;
import com.clpms.dao.mapper.LearnRecordDao;
import com.clpms.dao.mapper.WorkDao;
import com.clpms.dao.pojo.LearnRecord;
import com.clpms.dao.pojo.Work;
import com.clpms.service.LearnRecordService;
import com.clpms.utils.CommonException;
import com.clpms.utils.CurrentUser;
import com.clpms.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author caixinyong
 * @date 2023/5/12 3:56 PM
 */

@Service
@Slf4j
public class LearnRecordServiceImpl implements LearnRecordService {

    @Resource
    private LearnRecordDao learnRecordDao;
    @Resource
    private WorkDao workDao;

    @Override
    public Boolean addBatch(List<LearnRecordAddReq> reqList, Long workId) {
        CurrentUser currentUser = UserUtils.get();
        Work work = workDao.selectById(workId);

        List<LearnRecord> learnRecordList = reqList.stream().map(learnRecordAddReq -> {
            return LearnRecord.builder()
                    .progress(learnRecordAddReq.getProgress())
                    .score(learnRecordAddReq.getScore())
                    .remark(learnRecordAddReq.getRemark())
                    .completionTime(learnRecordAddReq.getCompletionTime())
                    .easyType(learnRecordAddReq.getEasyType())
                    .schoolId(currentUser.getSchoolId())
                    .teacherId(currentUser.getTeacherId())
                    .courseId(work.getCourseId())
                    .workId(workId)
                    .build();
        }).collect(Collectors.toList());
        learnRecordDao.insertBatch(learnRecordList);
        return Boolean.TRUE;
    }

    @Override
    public UploadLearnRecordResp uploadLearnRecordFile(Long workId, MultipartFile file) {
        UploadLearnRecordResp resp = new UploadLearnRecordResp();
        CurrentUser currentUser = UserUtils.get();

        // 校验文件格式和大小。检查文件后缀名是否为.xls或.xlsx，以及文件大小是否在2MB以内
        String suffix =
                Objects.requireNonNull(file.getOriginalFilename())
                        .substring(file.getOriginalFilename().lastIndexOf("."));
        if (!".xls".equalsIgnoreCase(suffix) && !".xlsx".equalsIgnoreCase(suffix)) {
            throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(), "文件格式不正确");
        }
        if (file.getSize() > 2 * 1024 * 1024) {
            throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(), "文件大小超过限制");
        }

        try {
            // 创建Excel读取器
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            // 校验表头
            List<String> header = reader.readRow(0)
                    .stream()
                    .map(Cell -> Cell.toString().trim())
                    .collect(Collectors.toList());
            List<String> expectedHeader = Arrays.asList("进度", "分数", "完成时间", "难易程度", "备注");
            if (!expectedHeader.equals(header)) {
                throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(), "请使用正确的模板");
            }
            List<List<Object>> rows = reader.read();
            List<LearnRecord> records =
                    rows.stream()
                            .skip(1)
                            .map(row -> {
                                LearnRecord learnRecord = new LearnRecord();
                                if (row.size() > 0) {
                                    String progress = Objects.toString(row.get(0), "").trim(); // 第 1 列
                                    if (StringUtils.isNotBlank(progress)) { // 如果不为空字符串则设置值
                                        learnRecord.setProgress(LearnRecordProgress.getCodeByDesc(progress));
                                    }
                                }

                                if (row.size() > 1) {
                                    Double score = Convert.toDouble(row.get(1)); // 第 2 列
                                    if (score != null) { // 如果不为 null 则设置值
                                        learnRecord.setScore(score);
                                    }
                                }

                                if (row.size() > 2) {
                                    String completionTimeString = Objects.toString(row.get(2), "").trim(); // 第 3 列
                                    if (StringUtils.isNotBlank(completionTimeString)) { // 如果不为空字符串则设置值
                                        LocalDateTime completionTime =
                                                DateUtil.parseLocalDateTime(completionTimeString);
                                        learnRecord.setCompletionTime(Date.from(completionTime.atZone(ZoneId.systemDefault()).toInstant()));
                                    }
                                }

                                if (row.size() > 3) {
                                    String easyType = Objects.toString(row.get(3), "").trim(); // 第 4 列
                                    if (StringUtils.isNotBlank(easyType)) { // 如果不为空字符串则设置值
                                        learnRecord.setEasyType(EasyTypeEnum.getCodeByDesc(easyType));
                                    }
                                }

                                if (row.size() > 4) {
                                    String remark = Objects.toString(row.get(4), "").trim(); // 第 5 列
                                    if (StringUtils.isNotBlank(remark)) { // 如果不为空字符串则设置值
                                        learnRecord.setRemark(remark);
                                    }
                                }
                                learnRecord.setSchoolId(currentUser.getSchoolId());
                                learnRecord.setTeacherId(currentUser.getTeacherId());
                                learnRecord.setCourseId(workDao.selectById(workId).getCourseId());
                                learnRecord.setWorkId(workId);

                                return learnRecord;
                            }).collect(Collectors.toList());

            learnRecordDao.insertBatch(records);
            resp.setAllSuccessFlag(Boolean.TRUE);
            return resp;
        } catch (IOException e) {
            log.error("LearnRecordServiceImpl.uploadLearnRecordFile Exception", e);
            throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(), "文件解析失败");
        }
    }

    @Override
    public Boolean deleteBatch(DeleteLearnRecordReq req) {
        CurrentUser currentUser = UserUtils.get();
        learnRecordDao.deleteBatch(req.getLearnRecordIdList(), currentUser.getSchoolId(), currentUser.getTeacherId());
        return Boolean.TRUE;
    }

    @Override
    public Boolean updateLearnRecord(UpdateLearnRecordReq req) {
        CurrentUser currentUser = UserUtils.get();
        LearnRecord learnRecord = LearnRecord.builder()
                .id(req.getId())
                .progress(req.getProgress())
                .score(req.getScore())
                .remark(req.getRemark())
                .easyType(req.getEasyType())
                .schoolId(currentUser.getSchoolId())
                .teacherId(currentUser.getTeacherId())
                .build();
        learnRecordDao.updateById(learnRecord);
        return Boolean.TRUE;
    }
}
